// 所有声明周期方法名称
const hooks = ['beforeCreate', 'created', 'beforeMount', 'mounted',
    'beforeUpdate', 'updated', 'activated', 'deactivated', 'beforeDestroy', 'destroyed']

class Vue {
    constructor(options) {
        this.$options = Object.assign(Vue.options || {}, options || {})
        this.$data = options.data || {}
        this.$methods = options.methods || {}
        if (options && options.el) {
            this.$el = typeof options.el === 'string' ? document.querySelector(options.el) : options.el
        }
        this._proxyData(this.$data)
        this._proxyMethods(this.$methods)
        // 实现数据拦截
        new Observer(this.$data)
        // 启动模版编译
        new Compiler(this)
    }

    _proxyMethods(methods) {
        let obj = {}
        Object.keys(methods).forEach(key => {
            if (hooks.indexOf(key) === -1 && typeof methods[key] === 'function') {
                obj[key] = methods[key].bind(this)
            }
        })

        this._proxyData(obj)
    }

    _proxyData(data) {
        Object.keys(data).forEach(key => {
            Object.defineProperty(this, key, {
                enumerable: true,
                configurable: true,
                get() {
                    return data[key]
                },
                set(newValue) {
                    // 数据未发生任何变化，不需要处理
                    if (newValue === data[key]) {
                        return
                    }
                    data[key] = newValue
                }
            })
        })
    }

    // 用于注册指令的方法
    static directive(name, handle) {
        if (!Vue.options) {
            Vue.options = {
                directives: {}
            }
        }

        Vue.options.directives[name] = {
            bind: handle,
            update: handle
        }
    }
}